﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using System.Windows;
using MimiDouban.Abstract;
using System.Threading;
using System.Windows.Threading;
using MimiDouban.Extention;

namespace MimiDouban.Player
{
    /// <summary>
    /// 播放器实现类
    /// </summary>
    public class AudioPlayer : IPlayer
    {
        /// <summary>
        /// Windows MedeaPlayer
        /// </summary>
        private MediaPlayer mplayer;
        /// <summary>
        /// 定时器
        /// </summary>
        private Timer timer;
        /// <summary>
        /// 定时器回调处理器
        /// </summary>
        private TimerCallback timerHandler;
        /// <summary>
        /// 派发器
        /// </summary>
        private Dispatcher dispatcher;
        /// <summary>
        /// 当前是否暂停
        /// </summary>
        private bool boolIsPaused;

        #region IPlayer Members

        /// <summary>
        /// 初始化
        /// </summary>
        public AudioPlayer()
        {            
            mplayer = new MediaPlayer();//构造新对象
            timerHandler = new TimerCallback(timerHandlerMethod);
            dispatcher = Dispatcher.CurrentDispatcher;

            //绑定事件处理方法
            mplayer.BufferingStarted += new EventHandler(mplayer_BufferingStarted);
            mplayer.BufferingEnded += new EventHandler(mplayer_BufferingEnded);
            mplayer.MediaFailed += new EventHandler<ExceptionEventArgs>(mplayer_MediaFailed);
            mplayer.MediaEnded += new EventHandler(mplayer_MediaEnded);

            ((System.ComponentModel.ISupportInitialize)(mplayer)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(mplayer)).EndInit();
        }

        /// <summary>
        /// 是否暂停
        /// </summary>
        /// <returns></returns>

        public bool isPaused()
        {
            return boolIsPaused;
        }

        /// <summary>
        /// 播放
        /// </summary>
        /// <param name="url"></param>

        public void play(string url)
        {
            if (timer != null)
            {
                timer.Dispose();
            }
            timer = new Timer(new TimerCallback(timerHandlerMethod));    
            timer.Change(10, 10);
            boolIsPaused = false;
            mplayer.Stop();
            mplayer.Open(new Uri(url));
            mplayer.Play();
        }

        /// <summary>
        /// 暂停
        /// </summary>
        public void pause()
        {
            boolIsPaused = true;
            mplayer.Pause();
        }        

        /// <summary>
        /// 恢复
        /// </summary>
        public void resume()
        {
            boolIsPaused = false;
            mplayer.Play();
        }        
        
        /// <summary>
        /// 设置音量
        /// </summary>
        /// <param name="vol">新的音量</param>
        public void setVolume(double vol)
        {
            mplayer.Volume = vol;
        }

        public double getVolume()
        {
            return mplayer.Volume;
        }

        /// <summary>
        /// 销毁播放器
        /// </summary>
        public void distroy()
        {
            mplayer.Stop();
        }

        public event PlayerEventHandler BufferingBegin;

        public event PlayerEventHandler BufferingEnd;

        public event PlayerFailedEventHandler PlayFailed;

        public event PlayerEventHandler PlayFinished;

        public event PlayerTickEventHandler PlayerTicked;

        #endregion

        #region Private Event Handler

        private void mplayer_MediaEnded(object sender, EventArgs e)
        {
            if (PlayFinished != null)
            {
                PlayFinished.Invoke();
            }
        }

        private void mplayer_MediaFailed(object sender, ExceptionEventArgs e)
        {
            if (PlayFailed != null)
            {
                PlayFailed.Invoke(e.ErrorException);
            }
        }

        private void mplayer_BufferingEnded(object sender, EventArgs e)
        {
            if (BufferingEnd != null)
            {
                BufferingEnd.Invoke();
            }
        }

        private void mplayer_BufferingStarted(object sender, EventArgs e)
        {
            if (BufferingBegin != null)
            {
                BufferingBegin.Invoke();
            }
        }

        private void triggerTickMethod()
        {
            if (PlayerTicked != null && mplayer != null)
            {
                PlayerTicked.Invoke((int)this.mplayer.Position.TotalSeconds);
            }        
        }

        private void timerHandlerMethod(object arg)
        {
            this.dispatcher.Invoke(new TickDelegate(triggerTickMethod),null);
        }

        #endregion

    }

    public delegate void TickDelegate();
}
